import Button from '@/component/Button';
import { Dropdown } from '@/component/Dropdown';
import Show from '@/component/Show';
import useToast from '@/component/Toast';
import useShortcut from '@/hooks/useShortcut';
import Workspace, { IFileInfo } from '@/pages/CodeEditor/workspace';
import * as monaco from 'monaco-editor';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { ActivtyBar } from './ActivtyBar';
import { ExplorerLogic } from './ExplorerLogic';
import styles from './index.module.less';
import { Drawer } from '@/component/Drawer';
import { ExplorerItemView } from './ExplorerItemView';
Workspace.get("test").then(r => {
  (window as any).Workspace = r
})

export interface IIFileInfo2 extends IFileInfo {
  depth: number;
}
export default function CodeEditorPage() {
  const file_list_div_ref = useRef<HTMLDivElement>(null)
  const ref_container_div = useRef<HTMLDivElement>(null)
  const editor_ref = useRef<monaco.editor.IStandaloneCodeEditor | null>(null)
  const editor = editor_ref.current;
  const [banner, setBanner] = useState<HTMLDivElement | null>(null)
  const file_list_logic_ref = useRef<ExplorerLogic | undefined>(void 0);

  useEffect(() => {
    const editor = editor_ref.current = monaco.editor.create(ref_container_div.current!, {
      value: ['function x() {', '\tconsole.log("Hello world!");', '}'].join('\n'),
      language: 'javascript',
      theme: 'vs-dark',
      automaticLayout: true,
    });
    const ele = document.createElement('div');
    ele.className = styles.code_editor_banner;
    setBanner(ele)
    const tids = [
      window.setTimeout(() => editor.setBanner(ele, 35), 1000),
    ];
    return () => {
      tids.forEach(window.clearTimeout)
      editor.dispose()
      editor_ref.current = null
    }
  }, [])

  const pickFiles = (opts?: { accept?: string; multiple?: boolean }) => new Promise<FileList>((resolve, reject) => {
    const i = document.createElement('input')
    i.type = 'file';
    Object.assign(i, opts)
    i.onchange = () => i.files?.length ? resolve(i.files) : reject("null");
    i.oncancel = () => reject('cancelled');
    i.onerror = e => reject(`[error]${e}`);
    i.click()
  })

  const onClickOpen = async () => {
    if (!editor) return;
    const file = (await pickFiles())[0]
    const langs = monaco.languages.getLanguages()
    const file_type = file.type
    const file_name = file.name.toLowerCase()
    const lang =
      langs.find(v => v.extensions?.find(v => file_name.endsWith(v))) ||
      langs.find(v => v.mimetypes?.includes(file_type))
    const model = editor.getModel()
    if (model) monaco.editor.setModelLanguage(model, lang?.id ?? "plaintext")
    editor?.setValue(await file.text())
  }

  const on_click_save_ref = useRef(() => { })
  useShortcut(['ctrl', 's'], useCallback(() => on_click_save_ref.current(), []));
  const [toast, toastCtx] = useToast()
  const toastRef = useRef(toast)
  toastRef.current = toast;

  useEffect(() => {
    if (file_list_logic_ref.current) return;
    const workspace_name = 'test'
    const logic = file_list_logic_ref.current = new ExplorerLogic();
    logic.set_workspace_name(workspace_name);
    logic.set_div(file_list_div_ref.current);
    logic.on_file_open = (info, content) => {
      const editor = editor_ref.current;
      if (!editor) return;
      const file_name = info.name.toLowerCase()
      const langs = monaco.languages.getLanguages()
      const lang = langs.find(v => v.extensions?.find(v => file_name.endsWith(v)))
      const model = editor.getModel()
      if (model) monaco.editor.setModelLanguage(model, lang?.id ?? "plaintext")
      editor.setValue(content)
      on_click_save_ref.current = () => Workspace.get(workspace_name)
        .then(r => r.save_file(info.id, editor.getValue()))
        .then(() => toastRef.current('保存成功'))
        .catch(e => toastRef.current('' + e))
    }
  }, [])

  const [is_primary_side_bar_open, set_primary_side_bar_open] = useState(true);

  const activty_bar_items: ActivtyBar.ItemInfo[] = useMemo(() => [{
    children: `📂`,
    onClick: () => set_primary_side_bar_open(v => !v),
    shortcut: ['ctrl', 'shift', 'e']
  }], [set_primary_side_bar_open]);



  return (
    <div className={styles.root}>
      {toastCtx}
      <div className={styles.top_bar}>
        
      </div>
      <div className={styles.main_zone}>
        <ActivtyBar items={activty_bar_items} />
        <div className={styles.primary_side_bar}>
          <Drawer
            open={is_primary_side_bar_open}
            closeWidth={30}
            onChange={set_primary_side_bar_open}>
            <Dropdown triggers={['contextMenu']} menu={{
              items: [{
                children: 'shit',
                key: 'shit'
              }]
            }}>
              <ExplorerItemView icon=''>
                tests
              </ExplorerItemView>
            </Dropdown>
          </Drawer>
        </div>
        <div className={styles.coding_zone} >
          {banner ? createPortal(
            <div>
              <Button size='s' onClick={onClickOpen}>
                open
              </Button>
            </div>, banner
          ) : void 0}

          <div id={styles.monaco_editor_container} ref={ref_container_div} />
        </div>
      </div>
      {/* <div className={styles.bottom_bar}></div> */}
    </div>
  )
}


// const pc = new RTCPeerConnection({ iceServers: [{ urls: "stun:stun.mystunserver.tld" }] })
// pc.onicecandidate = ({ candidate }) => {
//   // signaler.send({ candidate })
// }
// let makingOffer = false;
// pc.onnegotiationneeded = async () => {
//   try {
//     makingOffer = true;
//     await pc.setLocalDescription();
//     // signaler.send({ description: pc.localDescription });
//   } catch (err) {
//     console.error(err);
//   } finally {
//     makingOffer = false;
//   }
// }